package com.biz.primus.ms.promotion.dao.po;

import com.biz.primus.base.enums.PromotionTypeEnum;
import com.biz.primus.base.exception.utils.AssertUtils;
import com.biz.primus.common.utils.JsonUtils;
import com.biz.primus.model.promotion.enums.LuckyOrderTypeEnum;
import com.biz.primus.model.promotion.enums.PromotionGiftTypeEnum;
import com.biz.primus.model.promotion.exception.PromotionExceptionType;
import com.biz.primus.model.promotion.vo.LuckyOrderPromotionGiftVo;
import com.biz.primus.model.promotion.vo.LuckyOrderPromotionRuleVo;
import com.biz.primus.model.promotion.vo.OrderPromotionDetailVo;
import com.biz.primus.model.promotion.vo.req.OrderPromotionReqDetailVo;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * 下单有礼促销
 *
 * @author david-liu
 */
@Entity
@Setter
@Getter
public class LuckyOrderPromotion extends BasePromotion {
    private static final long serialVersionUID = 8649420556764066184L;

    /**
     * 存放LuckyOrderPromotionRuleVo JSON字符串
     *
     * @see LuckyOrderPromotionRuleVo
     */
    private String promotionRule;

    /**
     * 下单有礼类型(按照时间段设置中奖还是按照当日下单数量设置中奖)
     */
    @Enumerated(value = EnumType.STRING)
    private LuckyOrderTypeEnum luckyOrderType;

    // 赠品类型
    @Enumerated(value = EnumType.STRING)
    private PromotionGiftTypeEnum giftType;

    /**
     * 赠品规则详情, 存放LuckyOrderPromotionGiftVo JSON信息
     *
     * @see LuckyOrderPromotionGiftVo
     */
    @Column(columnDefinition = "TEXT")
    private String giftDetail;

    /**
     * 促销生效的门槛金额
     */
    private Integer limitAmount;

    @Override
    public boolean isMatchPromotionRule(OrderPromotionReqDetailVo detailVo) {
        AssertUtils.isTrue(Objects.nonNull(detailVo), PromotionExceptionType.ILLEGAL_PARAMETER);
        detailVo.postProcess();
        List<Long> promotionEffectProductIds = this.getPromotionEffectProductIds(detailVo);
        if (CollectionUtils.isEmpty(promotionEffectProductIds)) {
            return false;
        }
        Integer orderAmount = promotionEffectProductIds.stream().map(detailVo::getProductAmount).reduce(0, (acc, item) -> acc = acc + item);
        if ((orderAmount < limitAmount) || !this.isNowInPromotionEffectPeriod()) {
            return false;
        }
        LuckyOrderPromotionRuleVo luckyOrderPromotionRuleVo = this.getLuckyOrderPromotionRuleVo();
        if (Objects.isNull(luckyOrderPromotionRuleVo)) {
            return false;
        }

        if (luckyOrderPromotionRuleVo.getLuckyOrderType() == LuckyOrderTypeEnum.BY_ORDER_TIME_RANGE) {
            LocalDateTime now = LocalDateTime.now();
            if (Objects.isNull(luckyOrderPromotionRuleVo.getLuckyOrderStartTime())
                    || Objects.isNull(luckyOrderPromotionRuleVo.getLuckyOrderEndTime())
                    || now.isAfter(luckyOrderPromotionRuleVo.getLuckyOrderEndTime())
                    || now.isBefore(luckyOrderPromotionRuleVo.getLuckyOrderStartTime())) {
                return false;
            }
        }

        if (luckyOrderPromotionRuleVo.getLuckyOrderType() == LuckyOrderTypeEnum.BY_DAY_ORDER_SEQUENCE) {
            if (CollectionUtils.isEmpty(luckyOrderPromotionRuleVo.getLuckyOrderSequence())
                    || !luckyOrderPromotionRuleVo.getLuckyOrderSequence().contains(detailVo.getDayOrderNo())) {
                return false;
            }
        }

        if (luckyOrderPromotionRuleVo.getLuckyOrderType() == LuckyOrderTypeEnum.BY_DAY_ORDER_SEQUENCE) {
            if (CollectionUtils.isEmpty(luckyOrderPromotionRuleVo.getLuckyOrderSequence())
                    || !luckyOrderPromotionRuleVo.getLuckyOrderSequence().contains(detailVo.getLuckyOrderTimePeriodNo())) {
                return false;
            }
        }

        return true;
    }

    @Override
    public OrderPromotionDetailVo getOrderPromotionDetail(OrderPromotionReqDetailVo reqDetailVo) {
        AssertUtils.isTrue(Objects.nonNull(reqDetailVo), PromotionExceptionType.ILLEGAL_PARAMETER);
        reqDetailVo.postProcess();
        List<Long> promotionEffectProductIds = this.getPromotionEffectProductIds(reqDetailVo);
        if (CollectionUtils.isEmpty(promotionEffectProductIds)) {
            return null;
        }
        if (Objects.isNull(this.getLuckyOrderPromotionGiftVo())) {
            return null;
        }
        OrderPromotionDetailVo detailVo = new OrderPromotionDetailVo();
        detailVo.setId(this.getId());
        detailVo.setName(this.getName());
        detailVo.setDescription(this.getDescription());
        detailVo.setAllowCoupon(this.getAllowCoupon());
        detailVo.setPromotionType(PromotionTypeEnum.LUCKY_ORDER);
        detailVo.setEffectProductIds(promotionEffectProductIds);
        detailVo.setLuckyOrderPromotionGift(this.getLuckyOrderPromotionGiftVo());
        return detailVo;
    }

    public LuckyOrderPromotionGiftVo getLuckyOrderPromotionGiftVo() {
        if (StringUtils.isBlank(this.giftDetail)) {
            return null;
        }
        return JsonUtils.json2Obj(this.giftDetail, LuckyOrderPromotionGiftVo.class);
    }

    private LuckyOrderPromotionRuleVo getLuckyOrderPromotionRuleVo() {
        if (StringUtils.isBlank(this.promotionRule)) {
            return null;
        }
        return JsonUtils.json2Obj(this.promotionRule, LuckyOrderPromotionRuleVo.class);
    }
}
